/**
 @ Name：layui.aliyunOSS 阿里云oss直传 
	注意：需要服务器和回调配合
 */


layui.define(['upload', 'form'], function(exports) { //假如该组件依赖 layui.form
	var $ = layui.$,
		form = layui.form,
		upload = layui.upload,
		successCount = 0,
		successFiles = {},
		//字符常量
		MOD_NAME = 'aliyunOSS',
		ELEM = '.layui-aliyunOSS'

		//外部接口
		,
		aliyunOSS = {
			index: layui.aliyunOSS ? (layui.aliyunOSS.index + 10000) : 0

				//设置全局项
				,
			set: function(options) {
					var that = this;
					that.config = $.extend({}, that.config, options);
					return that;
				}

				//事件监听
				,
			on: function(events, callback) {
				return layui.onevent.call(this, MOD_NAME, events, callback);
			}
		}

		//操作当前实例
		,
		thisAliyunOSS = function() {
			var that = this,
				options = that.config,
				id = options.id || options.index;

			return {
				reload: function(options) {
					that.reload.call(that, options);
				},
				config: options
			}
		}

		//构造器
		,
		Class = function(options) {
			var that = this;
			that.index = ++aliyunOSS.index;
			that.config = $.extend({}, that.config, aliyunOSS.config, options);
			that.render();
		};

	//默认配置
	Class.prototype.config = {
		callback: false, //是否回调 默认false
		multiple: false, //是否多文件长传
		number: 20, //可上传张数，多文件上传有效
		allDone: function(result) { //所有上传陈工回调

		},
		success: function(result) { //单个上传回调

		},
		fail: function(e) { //报错回调

		}
	};

	//渲染视图
	Class.prototype.render = function() {
		var that = this,
			options = that.config;

		options.elemEvent = $(options.elem);
		
		var multiple = options.multiple;

		if (!options.fileType) {
			layer.msg('请选择文件类型');
			return;
		}
		var exts = options.fileSuffix;
		switch (options.fileType) {
			case 'images':
				if (!options.fileSuffix) {
					exts = 'jpg|png|gif|bmp|jpeg';
				}
				break;
			case 'video':
				if (!options.fileSuffix) {
					exts = 'mp4';
				}
				break;
			case 'audio':
				if (!options.fileSuffix) {
					exts = 'mp3';
				}
				break;
		}
		let extsArray = exts.split('|');
		let acceptMime = [];
		for (var i = 0; i < extsArray.length; i++) {
			acceptMime.push((options.fileType == 'images' ? 'image' : options.fileType) + '/' + extsArray[
				i])
		}
		if (multiple) { //多文件上传
		options.number = options.number?options.number:20;
			var uploadInst = upload.render({
				elem: options.elem,
				multiple: true,
				auto: false,
				accept: options.fileType,
				exts: exts,
				number: options.number,
				acceptMime: acceptMime.join(","),
				//url: options.policyUrl, //改成您自己的上传接口
				choose: function(obj) {
					options.item = this.item[0];
					var files = that.files = obj.pushFile(); //将每次选择的文件追加到文件队列
					var count = 0;
					for (var fileKey in files) {
						count++;
					}
					if(this.number == 0 || count > this.number){
						layer.msg('上传个数超出限定', {icon: 5}); 
						obj.preview(function(index, file, result) {
							delete files[index]; //删除列表中对应的文件，一般在某个事件中使用
						});
						return;
					}
					layer.msg('上传中', {
						icon: 16,
						time: 0
					});

					var policy = {};
					$.ajax({
						url: options.policyUrl,
						//processData: false,
						//cache: false,
						//contentType: false,
						type: 'POST',
						data: {
							path: options.prefixPath
						},
						//async: false,
						success: function(res) {
							policy = res.data;

							for (var fileKey in files) {
								var name = files[fileKey].name;
								policy.key = policy.dirPath + '/' + that
									.randomString() + name.substring(name.lastIndexOf('.'));
								that.uploadFile(files, fileKey, count, policy);
							}
						},
						error: function() {
							obj.preview(function(index, file, result) {
								delete files[index]; //删除列表中对应的文件，一般在某个事件中使用
							});
							layer.msg('签名失败');
							options.fail(e);
							setTimeout(function() {
								layer.closeAll(); //疯狂模式，关闭所有层
								options.elemEvent.next()[0].value = '';
							}, 2000)
						},
					})
				},
				done: function(res) {

				},
				error: function() {

				}
			});
			that.uploadInst = uploadInst;
		} else { //单文件上传
			//常规使用 - 普通图片上传
			var uploadInst = upload.render({
				elem: options.elem,
				multiple: false,
				auto: false,
				accept: options.fileType,
				exts: exts,
				acceptMime: acceptMime.join(","),
				//url: options.policyUrl, //改成您自己的上传接口
				choose: function(obj) {
					options.item = this.item[0];
					layer.msg('上传中', {
						icon: 16,
						time: 0
					});
					var policy = {};
					$.ajax({
						url: options.policyUrl,
						//processData: false,
						//cache: false,
						//contentType: false,
						type: 'POST',
						data: {
							path: options.prefixPath
						},
						//async: false,
						success: function(res) {
							policy = res.data;
							obj.preview(function(index, file, result) {
								var name = file.name;
								policy.key = policy.dirPath + '/' + that
									.randomString() + name.substring(name
										.lastIndexOf('.'));
								var files = {};
								files[file.lastModified] = file;
								that.files = files;
								console.log(files)
								that.uploadFile(files, file.lastModified, 1,
									policy);
							});
						},
						error: function(e) {
							obj.preview(function(index, file, result) {
								delete files[index]; //删除列表中对应的文件，一般在某个事件中使用
							});
							options.fail(e);
							layer.msg('签名失败');
							setTimeout(function() {
								layer.closeAll(); //疯狂模式，关闭所有层
								options.elemEvent.next()[0].value = '';
							}, 2000);
						},
					})
				},
				done: function(res) {

				},
				error: function() {
					layer.msg('上传失败');
					setTimeout(function() {
						layer.closeAll(); //疯狂模式，关闭所有层
					}, 2000);
				}
			});
			that.uploadInst = uploadInst;
		}
	}

	/**
	 * 文件上传
	 * @param {Object} files
	 * @param {Object} indexKey
	 * @param {Object} count
	 * @param {Object} policy
	 */
	Class.prototype.uploadFile = function(files, indexKey, count, policy) {
		var that = this,
			options = that.config;
		try {
			var filedata = new FormData();
			filedata.append('key', policy.key);
			filedata.append('policy', policy.policy);
			filedata.append('OSSAccessKeyId', policy.OSSAccessKeyId);
			filedata.append('signature', policy.signature);
			filedata.append('success_action_status', 200);
			if (options.callback) {
				filedata.append('callback', policy.callback);
			}
			filedata.append('file', files[indexKey]);
			$.ajax({
				url: policy.host,
				processData: false,
				cache: false,
				contentType: false,
				type: 'POST',
				//async: false,
				data: filedata,
				success: function(res) {
					if (options.callback) {
						if (res.success == 1) {
							successCount++;
							successFiles[indexKey] = res;
							options.success(res);
							if (successCount >= count) {
								options.allDone(successFiles);
								that.successAll();
							}
							delete that.files[indexKey];
						} else {
							delete that.files[indexKey];
						}
					} else {
						successCount++;
						successFiles[indexKey] = {
							'authc': 1,
							'success': 1,
							'data': {
								'fileName': this.data.get("key"),
								'size': files[indexKey].size,
								'mimeType': files[indexKey].type,
								'url': policy.host + '/' + this.data.get("key")
							}
						};
						options.success(successFiles[indexKey]);
						if (successCount >= count) {
							options.allDone(successFiles);
							that.successAll();
						}
						delete that.files[indexKey];
					}
				},
				error: function(e) {
					that.fail(e);
					delete that.files[indexKey];
				},
			})
		} catch (e) {
			that.fail(e);
			delete that.files[indexKey];
		}
	}

	//全部上传成功
	Class.prototype.successAll = function(e) {
		var that = this,
			options = that.config;
		layer.msg('上传成功');
		options.elemEvent.next()[0].value = '';
		setTimeout(function() {
			layer.closeAll(); //疯狂模式，关闭所有层
			successCount = 0;
			successFiles = {};
		}, 2000)
	}

	//上传失败
	Class.prototype.fail = function(e) {
		var that = this,
			options = that.config;
		options.fail(e);
		layer.msg('上传失败');
		setTimeout(function() {
			layer.closeAll(); //疯狂模式，关闭所有层
		}, 2000)
	}

	// 随机生成32位字符串
	Class.prototype.randomString = function() {
		let len = 32;
		let $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz12345678@';
		let maxPos = $chars.length;
		let pwd = '';
		for (let i = 0; i < len; i++) {
			pwd += $chars.charAt(Math.floor(Math.random() * maxPos))
		}
		return pwd;
	}

	//重置方法
	Class.prototype.reload = function(options) {
		options = options || {};
		delete options.elemEvent;
		var that = this,
			options = that.config = $.extend({}, that.config, options);
		that.uploadInst.reload(options);
	};

	//核心入口
	aliyunOSS.render = function(options) {
		var ins = new Class(options);
		return thisAliyunOSS.call(ins);
	};

	exports('aliyunOSS', aliyunOSS);
});
